package com.xiaoniu.forum.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaoniu.forum.common.constant.ForumConstant;
import com.xiaoniu.forum.common.event.ForumEvent;
import com.xiaoniu.forum.entity.vo.AppFollowFansNumVo;
import com.xiaoniu.forum.entity.vo.AppUserFollowStatusVo;
import com.xiaoniu.forum.service.MemberMessageService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoniu.forum.common.utils.PageUtils;
import com.xiaoniu.forum.common.utils.Query;

import com.xiaoniu.forum.dao.MemberFollowDao;
import com.xiaoniu.forum.entity.MemberFollowEntity;
import com.xiaoniu.forum.service.MemberFollowService;
import org.springframework.transaction.annotation.Transactional;


@Service("memberFollowService")
public class MemberFollowServiceImpl extends ServiceImpl<MemberFollowDao, MemberFollowEntity> implements MemberFollowService {

    private final String COLUMN_FOLLOWER_ID = "follower_id";//关注者字段名
    private final String COLUMN_USER_ID = "user_id";//被关注者字段名

    @Autowired
    private MemberMessageService messageService;
    /**
     * 根据用户id，查询他的关注、粉丝数量
     */
    @Override
    public AppFollowFansNumVo queryFollowFansNum(String id) {
        AppFollowFansNumVo followFansNumVo = new AppFollowFansNumVo();
        //查询该用户的关注数
        QueryWrapper<MemberFollowEntity> followWrapper = new QueryWrapper<>();
        followWrapper.eq(COLUMN_FOLLOWER_ID,id);//关注者id为当前用户的记录就就记录着用户关注了谁
        followFansNumVo.setFollowNum(this.count(followWrapper));

        //查询该用户的粉丝数
        QueryWrapper<MemberFollowEntity> fansWrapper = new QueryWrapper<>();
        fansWrapper.eq(COLUMN_USER_ID,id);//被关注者id为当前用户的记录就就记录着用户的粉丝
        followFansNumVo.setFansNum(this.count(fansWrapper));
        return followFansNumVo;
    }


    /**
     *  根据用户id。查询分页查询该用户的粉丝列表
     */
    @Override
    public PageUtils listFans(String userId, Page page) {
        QueryWrapper<MemberFollowEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(COLUMN_USER_ID,userId);//被关注者id为当前用户的记录就就记录着用户的粉丝列表
        queryWrapper.select(COLUMN_FOLLOWER_ID);//只查粉丝的id即可
        page.addOrder(OrderItem.asc("create_time"));
        List<MemberFollowEntity> follows = this.page(page, queryWrapper).getRecords();
        List<String> ids = new ArrayList<>();
        follows.forEach((follow)->ids.add(follow.getFollowerId()));
        page.setRecords(ids);
        return new PageUtils(page);
    }

    /**
     *  根据用户id。查询分页查询该用户的关注列表
     */
    @Override
    public PageUtils listFollows(String userId, Page page) {
        QueryWrapper<MemberFollowEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(COLUMN_FOLLOWER_ID,userId);//关注者id为当前用户的记录就就记录着用户关注了谁
        queryWrapper.select(COLUMN_USER_ID);//只查被关注的用户的id即可
        page.addOrder(OrderItem.asc("create_time"));
        List<MemberFollowEntity> follows = this.page(page, queryWrapper).getRecords();
        List<String> ids = new ArrayList<>();
        follows.forEach((follow)->ids.add(follow.getUserId()));
        page.setRecords(ids);
        return new PageUtils(page);
    }

    /**
     * 关注用户
     */

    @Transactional
    @Override
    public void follow(String followerId, String userId) {
        MemberFollowEntity followInfo = findByFollowerIdUserId(followerId, userId);
        if (followInfo != null) return;//重复关注，无需处理
        followInfo = new MemberFollowEntity();
        followInfo.setFollowerId(followerId);
        followInfo.setUserId(userId);
        this.save(followInfo);
        //保存关注事件
        ForumEvent event = new ForumEvent();
        event.setTriggerId(followerId);
        event.setTargetId(userId);
        event.setAction(ForumConstant.FOLLOW_ACTION);
        event.setData(ForumConstant.KEYNAME_ENTITY_TYPE,ForumConstant.USER_ENTITY_TYPE);
        messageService.sendEvent(event);
    }

    /**
     * 取消关注
     */
    @Override
    public void cancelFollow(String followerId, String userId) {
        MemberFollowEntity followInfo = findByFollowerIdUserId(followerId, userId);
        if (followInfo == null) return;//未关注，无需处理
        this.removeById(followInfo.getId());
    }

    @Override
    public boolean isFollow(String followerId, String userId) {
        MemberFollowEntity followInfo = findByFollowerIdUserId(followerId, userId);
        return followInfo==null?false:true;
    }

    /**
     * 查询当前用户是否已关注了另一批用户
     * 思路：
     *    前端：如果用户未登录，那么就是全部都未关注
     *          如果用户已登录，那么就批量查询关注状态
     *
     *    后端：
     *          查询关注者为当前用户，并且“被关注者id”存在这批用户中的记录
     */
    @Override
    public List<AppUserFollowStatusVo> batchQueryIsFollow(String userId, List<String> ids) {
        QueryWrapper<MemberFollowEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(COLUMN_FOLLOWER_ID,userId);
        queryWrapper.in(COLUMN_USER_ID,ids);

        //遍历id集合。如果id集合对应的记录不为null，那么当前用户就已关注了该用户，否则就是未关注
        List<AppUserFollowStatusVo> userFollowStatusVos = new ArrayList<>();
        List<MemberFollowEntity> followInfos = this.list(queryWrapper);
        for (String id:ids) {
            AppUserFollowStatusVo followStatus = new AppUserFollowStatusVo();
            followStatus.setUserId(id);
            followStatus.setStatus(false);
            for (MemberFollowEntity followInfo:followInfos) { //查看id是否有对应的记录，有的话就是已关注
                if (followInfo.getUserId().equals(id)){
                    followStatus.setStatus(true);
                    break;
                }
            }
            userFollowStatusVos.add(followStatus);
        }

        return userFollowStatusVos;
    }


    /**
     *  根据关注者以及被关注者查询记录
     */
    private MemberFollowEntity findByFollowerIdUserId(String followerId, String userId){
        QueryWrapper<MemberFollowEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(COLUMN_FOLLOWER_ID,followerId);
        queryWrapper.eq(COLUMN_USER_ID,userId);
        MemberFollowEntity followInfo = this.getOne(queryWrapper);
        return  followInfo;
    }


}